package tutorial.main.control;

import java.net.NetworkInterface;
import java.util.ArrayList;

import com.google.android.maps.GeoPoint;

import android.content.Context;
import tutorial.entidades.Evento;
import tutorial.main.control.location.LocationFinder;
import tutorial.main.control.widget.WidgetControler;
import tutorial.main.data.GestorBDLista;
import tutorial.main.data.ProviderRegistro;
import tutorial.main.vista.GrillaDeEstados;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;

public class NetChangeService extends Service{

	private ConectivityListener _listener = new ConectivityListener();
	private NetworkConnectivtyHandler _handler = new NetworkConnectivtyHandler();
	private Context yo;
	private int id_evento_nuevo;
	private Evento eventoNuevo;
	private LocationFinder lf;
	public static String ESTADO_CONEXION="ESTADO_CONEXION";
	public static String RED_CONEXION="RED_CONEXION";
	
	private static boolean iniciado=false;
	
	private ArrayList<Notificable> notificables;
	// Este es el objeto que interactua con los clientes !!!
	private final IBinder mBinder = new LocalBinder();
	
	@Override
	public IBinder onBind(Intent intent) {
		Log.v("NetChangeService","OnBind");
		return mBinder;
	}

	@Override
	public void onCreate() 
	{
		super.onCreate();
		notificables = new ArrayList<Notificable>();
		Log.v("NetChangeService","OnCreate");
		yo=this;
		// Creo el servicio para calcular las coordenadas de la conexion
		lf = new LocationFinder((LocationManager)getSystemService(Context.LOCATION_SERVICE));
        try
        {
        	lf.startListening(locListener);
        }
        catch(Exception e)
        {
        	Log.i(LOCATION_SERVICE,"El GPS NO ESTA ENCENDIDO");
        }		
        iniciado=true;
	}

	@Override
	public void onDestroy() {
		//Aviso al widget
		WidgetControler.notificarCierre(yo);
		
		_listener.UnregisterListening();
		super.onDestroy();
		Log.v("NetChangeService","OnDestroy");
		iniciado=false;
	}
	
	@Override
	public void onStart(Intent intent, int startId) 
	{
		super.onStart(intent, startId);
		_listener.RegisterListening(this);
		_listener.RegisterHandler(_handler,9);
		Log.v("NetChangeService","OnStart");
	}
	
	

	
	public void RegisterNotificable(Notificable notificable) 
	{
		Log.v("NetChangeService","RegisterNotificable");
		notificables.add(notificable);
	}

	public void UnregisterNotificable(Notificable notificable) 
	{
		Log.v("NetChangeService","UnregisterNotificable");
		notificables.remove(notificable);
	}
	
	public void EventoDeCambioDeConexion(Bundle info)
	{
		// - HOLA, TENGO UN CAMBIO DE CONEXION !!!
		// - AJA, y yo que hago?
		// - Mmm, y nose, avisale a alguien que le importe
		// - Bueno !! creo que son los notificables, por aca tengo una lista
		eventoNuevo = new Evento();	
		
			Log.v("NetChangeService","Estado: "+info.getBoolean("conectado"));		
			
			//Carga en la lista de eventos almacenados en otras sesiones
			id_evento_nuevo=(GestorBDLista.ultimoNmro( yo)+1);	
			//Coloca id al evento
			eventoNuevo.setId(id_evento_nuevo);
			eventoNuevo.setEstadoConetado(info.getBoolean("conectado"));
			eventoNuevo.setMomento(info.getLong("fecha"));
			eventoNuevo.setReason(info.getString("reason"));
			eventoNuevo.setSincronizado(false);
			eventoNuevo.setSubtipoConexion(info.getString("subnet"));
			eventoNuevo.setTipoConexion(info.getString("nettype"));
			eventoNuevo.setCodUsuario(SConfig.getSingleton().getCi());
			
			// Coordenadas del evento
			GeoPoint plf = lf.getLastPosition();
			if(plf!=null)
			{
				eventoNuevo.setPosicion(plf);
			}
			
			// Antes de notificar, aviso al usuario con un Notification cuac
			NotificationServer ns = new NotificationServer();
			ns.NotificarConexion(yo, eventoNuevo);
			
			//Notifico al widget
			Intent intent = new Intent(WidgetControler.ACTUALIZAR_EVENTO);
			intent.putExtra( ESTADO_CONEXION, eventoNuevo.getEstadoConetado());
			if(eventoNuevo.getEstadoConetado())
			{intent.putExtra( RED_CONEXION, eventoNuevo.getTipoConexion()+" - "+eventoNuevo.getSubtipoConexion());}
			else
			{intent.putExtra( RED_CONEXION,"");}
			sendBroadcast(intent);
			Log.v( "Servicio", "Wdgt Broadcast enviado");
		for (Notificable aMi : notificables) 
		{
			aMi.notificar(eventoNuevo);
		}
	}
	
	public class LocalBinder extends Binder 
	{
		public NetChangeService getService() 
		{
			return NetChangeService.this;
		}
	}
	
	/**
	 * Este handler es el que hace todo el manejo de los cambios de estado. Utiliza
	 * el ConnectivityStateListener (que esta escuchando los cambios de estado en la
	 * conectividad) para decidir que hacer de acuerdo a lo que sucede.
	 */
	private class NetworkConnectivtyHandler extends Handler {

		private Boolean _connected;

		@Override
		public void handleMessage(Message msg) 
		{
			
			boolean connected = _listener.isConnected();
			if(connected)
			{
				// Aca deberia estar conectado ...
				// Busco la info
				Bundle info = _listener.getNetworkInfo();
				Log.v("NetChangeService","CONRED: "+info.getString("Info"));
				EventoDeCambioDeConexion(info);
			}
			else
			{
				Bundle info = _listener.getNetworkInfo();
				Log.v("NetChangeService","SINRED: "+info.getString("Info"));
				EventoDeCambioDeConexion(info);
			}
//
//			
	}
	}
	
	LocationListener locListener = new LocationListener()
	{
		//  Lanzado cada vez que se recibe una actualización de la posición
		@Override
	    public void onLocationChanged(Location location) {

	    }
	 
	    //  Lanzado cuando el proveedor se deshabilita.
		@Override
	    public void onProviderDisabled(String provider){
	        
	    }
	 
	    //  Lanzado cuando el proveedor se habilita.
		@Override
	    public void onProviderEnabled(String provider){
	        
	    }
	 
	    // Lanzado cada vez que el proveedor cambia su estado, que puede variar entre OUT_OF_SERVICE, TEMPORARILY_UNAVAILABLE, AVAILABLE.
		@Override
	    public void onStatusChanged(String provider, int status, Bundle extras){
	        
	    }
	};
	
	//Para cuando se inicia el widget la 1ra vez
	/*public void callForWidgetNotification()
	{WidgetControler.notificarEvento(yo,eventoNuevo);}*/
	
	public static boolean servicioIniciado()
	{return iniciado;}
	
	
	
}


